<!DOCTYPE html>
<script src="../../resources/gesture-util.js"></script>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<style>
body {
  margin: 0;
  padding: 0;
}

#scroller {
  overflow: scroll;
  height: 300px;
  width: 300px;
  margin: 0;
  padding: 0;
  scroll-snap-type: y mandatory;
}

#container {
  margin: 0;
  padding: 0;
  width: 600px;
  height: 1833px; /* use a percentage of this to make snap offsets float numbers */
}

#initial-area {
  position: relative;
  top: 10%; /* ~183.3 */
  width: 200px;
  height: 200px;
  background-color: blue;
  scroll-snap-align: start;
}

#target-area {
  position: relative;
  top: 30%; /* ~549.9 */
  width: 200px;
  height: 200px;
  background-color: blue;
  scroll-snap-align: start;
}
</style>

<div id="scroller">
  <div id="container">
    <div id="initial-area"></div>
    <div id="target-area"></div>
  </div>
</div>

<script>
const scroller = document.getElementById('scroller');
const initial_area = document.getElementById('initial-area');
const target_area = document.getElementById('target-area');

function cleanup() {
  scroller.scrollTo(0, 183);
}

function keyPress(key) {
  return new Promise((resolve, reject) => {
    if (window.eventSender) {
      eventSender.keyDown(key);
      resolve();
    }
    else {
      reject('This test requires window.eventSender');
    }
  })
}

function scrollTop() {
  return scroller.scrollTop;
}

async function waitForScrollEndWithFractionalValue(targetElement, value) {
  return waitForScrollEnd(targetElement, () => {
    return Math.abs(scrollTop() - value) < 1;
  }, true);
}

promise_test (async t => {
  t.add_cleanup(cleanup);
  scroller.scrollTo(0, 183);
  assert_approx_equals(scrollTop(), initial_area.offsetTop, 1);

  await mouseClickOn(10, 10);
  await keyPress('ArrowDown');
  await waitForScrollEndWithFractionalValue(scroller, target_area.offsetTop);

  await keyPress('ArrowUp');
  await waitForScrollEndWithFractionalValue(scroller, initial_area.offsetTop);
}, "Keyboard scrolling should ignore the current snapped element even when its"
+ " offset is a fractional number.");

promise_test (async t => {
  t.add_cleanup(cleanup);
  assert_approx_equals(scrollTop(), initial_area.offsetTop, 1);

  scroller.scrollBy(0, 10);
  await waitForScrollEndWithFractionalValue(scroller, target_area.offsetTop);

  scroller.scrollBy(0, -10);
  await waitForScrollEndWithFractionalValue(scroller, initial_area.offsetTop);
}, "Programmatic directional scrolling should ignore the current snapped " +
   "element even when its offset is a fractional number.");

</script>
